/** 
 * This file is a part of qloudgen-sec. 
 * You can redistribute qloudgen-sec and/or modify it under the terms of the Lesser GNU General Public License version 3. 
 * qloudgen-sec is distributed WITHOUT ANY WARRANTY. 
 *
 * See the Lesser GNU General Public License for more details at http://www.gnu.org/licenses/. 
 **/
package org.qloudgen.sec.util;

import java.util.Date;
import java.util.Iterator;
import java.util.Enumeration;

import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>Title: HTTP protocol tools.</p>
 * <p>Description: Implementation http request and response print.</p>
 * <p>Copyright: qloudgen/sec 2010</p>
 * @author <a href="mailto:hyq.dd.sun@gmail.com">glue.3M</a>
 */
public final class HttpUtil {

	/**
	 *
	 */
	private final static Logger logger = LoggerFactory.getLogger( HttpUtil.class );

	/**
	 *
	 *
	 * @param request
	 * @param response
	 */
	public static void print(HttpServletRequest request , HttpServletResponse response) {
		//
		printRequest( request , response );
	}
	
	/**
	 *
	 *
	 * @param request
	 * @param response
	 */
	private static void printRequest(HttpServletRequest request , HttpServletResponse response) {
		int majorVersion = 0;
		int minorVersion = 0;
		StringBuilder buffer = new StringBuilder();
		buffer.append( "\n[Request]\n" );
		//
		if ( request != null ) {
			//
			HttpSession hs = request.getSession( false );// Only output not to create !
			if ( hs != null ) {
				buffer.append( "  |--[Session]\n" );
				buffer.append( "  |    |--Id:" ).append( hs.getId() ).append( "\n" );
				buffer.append( "  |    |--Create Time:" ).append( new Date( hs.getCreationTime() ) ).append( "\n" );
				buffer.append( "  |    |--Last Accessed Time:" ).append( new Date( hs.getLastAccessedTime() ) ).append( "\n" );
				buffer.append( "  |    |--Max Inactive Interval:" ).append( hs.getMaxInactiveInterval() ).append( "\n" );
				buffer.append( "  |    |--Is New:" ).append( hs.isNew() ).append( "\n" );
				buffer.append( "  |    |--Attributes:" );
				Enumeration<String> h = hs.getAttributeNames();
				while ( h.hasMoreElements() ) {
					String name = h.nextElement();
					buffer.append( name ).append( "-->" ).append( hs.getAttribute( name ) ).append( ";" );
				}
				buffer.append( "\n" );		
				//
				ServletContext sc = hs.getServletContext();
				majorVersion = sc.getMajorVersion();
				minorVersion = sc.getMinorVersion();
				//
				buffer.append( "  |--[Context]\n" );
				buffer.append( "  |    |--Server Info:" ).append( sc.getServerInfo() ).append( "\n" );
				buffer.append( "  |    |--Version:" ).append( majorVersion ).append( "." ).append( minorVersion ).append( "\n" );
				if ( majorVersion >= 3 ) {
					buffer.append( "  |    |--Class Loader:" ).append( sc.getClassLoader() ).append( "\n" );
				}
				buffer.append( "  |    |--Context Path:" ).append( sc.getContextPath() ).append( "\n" );
				buffer.append( "  |    |--Servlet Context Name:" ).append( sc.getServletContextName() ).append( "\n" );
				buffer.append( "  |    |--Init Parameters:" );
				Enumeration<String> sce = sc.getInitParameterNames();
				while ( sce.hasMoreElements() ) {
					String name = sce.nextElement();
					buffer.append( name ).append( "-->" ).append( sc.getInitParameter( name ) ).append( ";" );
				}
				buffer.append( "\n" );
				buffer.append( "  |    |--Attributes:" );
				Enumeration<String> sca = sc.getAttributeNames();
				while ( sca.hasMoreElements() ) {
					String name = sca.nextElement();
					buffer.append( name ).append( "-->" ).append( sc.getAttribute( name ) ).append( ";" );
				}
				buffer.append( "\n" );
			}
			//
			Cookie[] cs = request.getCookies();
			if ( cs != null ) {
				//
				buffer.append( "  |--[Cookie]\n" );
				for ( Cookie c : cs ) {
					buffer.append( "  |    |--Name:" ).append( c.getName() ).append( "\n" );
					buffer.append( "  |    |--Domain:" ).append( c.getDomain() ).append( "\n" );
					buffer.append( "  |    |--Path:" ).append( c.getPath() ).append( "\n" );
					buffer.append( "  |    |--Comment:" ).append( c.getComment() ).append( "\n" );
					buffer.append( "  |    |--Max Age:" ).append( c.getMaxAge() ).append( "\n" );
					buffer.append( "  |    |--Secure:" ).append( c.getSecure() ).append( "\n" );
					buffer.append( "  |    |--Value:" ).append( c.getValue() ).append( "\n" );
					if ( majorVersion >= 3 ) {
						buffer.append( "  |    |--Is Http Only:" ).append( c.isHttpOnly() ).append( "\n" );
					}
					buffer.append( "  |    |--Version:" ).append( c.getVersion() ).append( "\n" );
				}
			}
			//
			buffer.append( "  |--Protocol:" ).append( request.getProtocol() ).append( "\n" );
			buffer.append( "  |--Scheme:" ).append( request.getScheme() ).append( "\n" );
			buffer.append( "  |--Server Name:" ).append( request.getServerName() ).append( "\n" );
			buffer.append( "  |--Server Port:" ).append( request.getServerPort() ).append( "\n" );
			buffer.append( "  |--Character Encoding:" ).append( request.getCharacterEncoding() ).append( "\n" );
			buffer.append( "  |--Content Type:" ).append( request.getContentType() ).append( "\n" );
			buffer.append( "  |--Content Length:" ).append( request.getContentLength() ).append( "\n" );
			buffer.append( "  |--Locale:" ).append( request.getLocale() ).append( "\n" );
			buffer.append( "  |--Local Address:" ).append( request.getLocalAddr() ).append( "\n" );
			buffer.append( "  |--Local Port:" ).append( request.getLocalPort() ).append( "\n" );
			buffer.append( "  |--Local Name:" ).append( request.getLocalName() ).append( "\n" );
			buffer.append( "  |--Remote Address:" ).append( request.getRemoteAddr() ).append( "\n" );
			buffer.append( "  |--Remote Port:" ).append( request.getRemoteHost() ).append( "\n" );
			buffer.append( "  |--Remote Host:" ).append( request.getRemotePort() ).append( "\n" );
			//
			buffer.append( "  |--Attributes:" );
			Enumeration<String> ra = request.getAttributeNames();
			while ( ra.hasMoreElements() ) {
				String name = ra.nextElement();
				buffer.append( name ).append( "-->" ).append( request.getAttribute( name ) ).append( ";" );
			}
			buffer.append( "\n" );
			//
			buffer.append( "  |--Parameters:" );
			Enumeration<String> rp = request.getParameterNames();
			while ( rp.hasMoreElements() ) {
				String name = rp.nextElement();
				buffer.append( name ).append( "-->" );
				//
				String[] values = request.getParameterValues( name );
				for ( String v : values ) {
					buffer.append( v ).append( "|" );
				}
				buffer.append( ";" );
			}
			buffer.append( "\n" );
			//
			buffer.append( "  |--Auth Type:" ).append( request.getAuthType() ).append( "\n" );
			buffer.append( "  |--Context Path:" ).append( request.getContextPath() ).append( "\n" );
			buffer.append( "  |--Method:" ).append( request.getMethod() ).append( "\n" );
			buffer.append( "  |--Path Info:" ).append( request.getPathInfo() ).append( "\n" );
			buffer.append( "  |--Path Translated:" ).append( request.getPathTranslated() ).append( "\n" );
			buffer.append( "  |--Query String:" ).append( request.getQueryString() ).append( "\n" );
			buffer.append( "  |--Remote User:" ).append( request.getRemoteUser() ).append( "\n" );
			buffer.append( "  |--Request Session Id:" ).append( request.getRequestedSessionId() ).append( "\n" );
			buffer.append( "  |--Request URI:" ).append( request.getRequestURI() ).append( "\n" );
			buffer.append( "  |--Request URL:" ).append( request.getRequestURL() ).append( "\n" );
			buffer.append( "  |--Servlet Path:" ).append( request.getServletPath() ).append( "\n" );
			//
			buffer.append( "  |--Headers:" );
			Enumeration<String> rh = request.getHeaderNames();
			while ( rh.hasMoreElements() ) {
				String name = rh.nextElement();
				buffer.append( name ).append( "-->" );
				//
				Enumeration<String> rhv = request.getHeaders( name );
				while ( rhv.hasMoreElements() ) {
					buffer.append( rhv.nextElement() ).append( "|" );
				}
				buffer.append( ";" );
			}
			buffer.append( "\n" );
		}
		//
		buffer.append( "  <End>\n" );
		//
		logger.trace( buffer.toString() );
		//
		printResponse( response , majorVersion , minorVersion );
	}
	
	/**
	 *
	 *
	 * @param response
	 * @param majorVersion
	 * @param minorVersion
	 */
	private static void printResponse(HttpServletResponse response , int majorVersion , int minorVersion) {
		StringBuilder buffer = new StringBuilder();
		buffer.append( "\n[Response]\n" );
		//
		if ( response != null ) {
			//
			buffer.append( "  |--Buffer Size:" ).append( response.getBufferSize() ).append( "\n" );
			buffer.append( "  |--Character Encoding:" ).append( response.getCharacterEncoding() ).append( "\n" );
			buffer.append( "  |--Content Type:" ).append( response.getContentType() ).append( "\n" );
			buffer.append( "  |--Locale:" ).append( response.getLocale() ).append( "\n" );
			buffer.append( "  |--Is Committed:" ).append( response.isCommitted() ).append( "\n" );
			//
			if ( majorVersion >= 3 ) {
				buffer.append( "  |--Status:" ).append( response.getStatus() ).append( "\n" );
				buffer.append( "  |--Header:" );
				Iterator<String> headers = response.getHeaderNames().iterator();
				while ( headers.hasNext() ) {
					String name = headers.next();
					buffer.append( name ).append( "-->" ).append( response.getHeaders( name ) ).append( ";" );
				}
				buffer.append( "\n" );
			}
		}
		buffer.append( "  <End>\n" );
		//
		logger.trace( buffer.toString() );
	}
}